package team.scau.laboratory_repair.common.json;

import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.scau.laboratory_repair.common.activiti.dto.RepairProcDto;
import team.scau.laboratory_repair.common.activiti.dto.RepairTaskDto;
import team.scau.laboratory_repair.common.enums.RecordStatus;
import team.scau.laboratory_repair.common.utils.StringTool;
import team.scau.laboratory_repair.modules.dto.*;
import team.scau.laboratory_repair.modules.po.*;
import team.scau.laboratory_repair.service.*;

import java.util.*;

/**
 * @Description:未完成
 * @Author:ZTF
 * @Date:2018/5/23 16:25
 */
@Service
public class PoToDto {
    @Autowired
    private AreaService areaService;
    @Autowired
    private UserService userService;
    @Autowired
    private RecordService recordService;
    @Autowired
    private DomainService domainService;
    @Autowired
    private RepairClassifyService repairClassifyService;
    @Autowired
    private WechatUserService wechatUserService;
    @Autowired
    private ActivitiService activitiService;

    public static <T> String idStrings2NameStrings(String ids, Map<Long, String> map){
        List<Long> longs = StringTool.strings2LongList(ids);
        StringBuilder sb = new StringBuilder();
        for(Long l : longs){
            sb.append(map.get(l)).append(',');
        }
        sb.deleteCharAt(sb.length()-1);
        return sb.toString();
    }

    public AreaDto area(Area area){
        return AreaDto.builder().name(area.getName()).id(area.getId()).build();
    }
    public List<AreaDto> areaList(List<Area> areaList) throws Exception {
        List<User> managers = userService.listAllManager();
        Map<Long, String> managerMap = new TreeMap<>();
        for(User m : managers){
            managerMap.put(m.getId(), m.getUsername());
        }
        List<AreaDto> areaDtoList=new ArrayList<>();
        for(Area area:areaList){
            AreaDto dto = area(area);
            if(area.getManager()!=null){
                dto.setManager(managerMap.get(area.getManager()));
            }
            areaDtoList.add(dto);
        }
        return areaDtoList;
    }

    public RecordDto record(Record record){
        List<Area> areas = areaService.listOrByExample(null, null).getResults();
        String area = StringUtils.EMPTY;
        for(Area a : areas){
            if(a.getId().equals(record.getArea())){
                area = a.getName();
            }
        }
        return RecordDto.builder().id(record.getId()).area(area).room(record.getRoom())
                .equipmentId(record.getEquipmentId()).classify(repairClassifyService.getById(record.getClassify()).getName())
                .detail(record.getDetail()).build();
    }

    public List<RecordDto> recordList(List<Record> records){
        List<Area> areas = areaService.listOrByExample(null, null).getResults();
        Map<Long, String> areaMap = new HashMap<>();
        for(Area a : areas){
            areaMap.put(a.getId(), a.getName());
        }
        List<RecordDto> list = new ArrayList<>();
        for(Record record : records){
            RecordDto dto = RecordDto.builder().id(record.getId()).area(areaMap.get(record.getArea()))
                    .room(record.getRoom()).equipmentId(record.getEquipmentId())
                    .classify(repairClassifyService.getById(record.getClassify()).getName())
                    .detail(record.getDetail()).build();
            list.add(dto);
        }
        return list;
    }

    public List<RecordSubscriptionDto> recordSubscriptionList(List<RecordSubscription> recordSubscriptions){
        List<RecordSubscriptionDto> list = new ArrayList<>();
        for(RecordSubscription recordSubscription : recordSubscriptions){
            RecordSubscriptionDto dto = RecordSubscriptionDto.builder()
                    .principal(userService.findById(recordSubscription.getId()).getUsername())
                    .status(RecordStatus.valueOf(recordSubscription.getStatus()).toString())
                    .subscription(recordSubscription.getSubscription().toString())
                    .timestamp(StringTool.time2String(recordSubscription.getUpdateTime()))
                    .build();
            list.add(dto);
        }
        return list;
    }

    public List<RepairClassifyDto> repairClassifyList(List<RepairClassify> repairClassifies){
        List<Area> areas = areaService.listOrByExample(null, null).getResults();
        Map<Long, String> areaMap = new HashMap<>();
        for(Area a : areas){
            areaMap.put(a.getId(), a.getName());
        }
        List<RepairClassifyDto> list = new ArrayList<>();
        for(RepairClassify repairClassify : repairClassifies){
            RepairClassifyDto dto = RepairClassifyDto.builder().name(repairClassify.getName())
                    .area(areaMap.get(repairClassify.getLocationId())).id(repairClassify.getId())
                    .build();
            list.add(dto);
        }
        return list;
    }

    public List<DomainDto> domainDtoList(List<Domain> domains) throws Exception {
        List<Area> areas = areaService.findAll();
        Map<Long, String> areaMap = new TreeMap<>();
        for (Area a : areas){
            areaMap.put(a.getId(), a.getName());
        }
        List<User> users = userService.listAllStaff();
        Map<Long, String> staffMap = new TreeMap<>();
        for (User u : users){
            staffMap.put(u.getId(), u.getUsername());
        }
        List<DomainDto> list = new ArrayList<>();
        for (Domain d : domains){
            String staffs = idStrings2NameStrings(d.getStaffIds(),staffMap);
            list.add(new DomainDto(d.getId(), areaMap.get(d.getAreaId()), d.getRoom(), staffs));
        }
        return list;
    }

    public List<RepairTaskDto> taskDtoList(List<Task> tasks) throws Exception {
        List<RepairTaskDto> dtos = new LinkedList<>();
        List<User> allStaff = userService.listAllStaff();
        Map<Long, String> staffMap = new TreeMap<>();
        for(User u : allStaff){
            staffMap.put(u.getId(), u.getUsername());
        }
        for(Task t : tasks){
            String name = StringUtils.isNotBlank(t.getAssignee()) ? staffMap.get(Long.valueOf(t.getAssignee())) : "";
            dtos.add(new RepairTaskDto(t, name));
        }
        return dtos;
    }

    public RepairProcDto repairProcDto(HistoricProcessInstance h) throws Exception {
        List<User> allStaff = userService.listAllStaff();
        Map<Long, String> staffMap = new TreeMap<>();
        for (User u : allStaff) {
            staffMap.put(u.getId(), u.getUsername());
        }
        LinkedList<RepairTaskDto> dtos = new LinkedList<>();
        List<HistoricTaskInstance> tasks = activitiService.listHistoryTaskByProcId(h.getId());
        for (HistoricTaskInstance hh : tasks) {
            String name = StringUtils.isNotBlank(hh.getAssignee()) ? staffMap.get(Long.valueOf(hh.getAssignee())) : "";
            dtos.add(new RepairTaskDto(hh, name));
        }
        return new RepairProcDto(h, dtos, h.getProcessVariables());
    }

    public List<RepairProcDto> repairProcDtoList(List<HistoricProcessInstance> instances) throws Exception {
        List<RepairProcDto> list = new LinkedList<>();
        List<User> allStaff = userService.listAllStaff();
        Map<Long, String> staffMap = new TreeMap<>();
        for (User u : allStaff) {
            staffMap.put(u.getId(), u.getUsername());
        }
        for (HistoricProcessInstance h : instances) {
            LinkedList<RepairTaskDto> dtos = new LinkedList<>();
            List<HistoricTaskInstance> tasks = activitiService.listHistoryTaskByProcId(h.getId());
            for (HistoricTaskInstance hh : tasks) {
                String name = StringUtils.isNotBlank(hh.getAssignee()) ? staffMap.get(Long.valueOf(hh.getAssignee())) : "";
                dtos.add(new RepairTaskDto(hh, name));
            }
            list.add(new RepairProcDto(h, dtos, h.getProcessVariables()));
        }
        return list;
    }
}
